using System;
using System.Collections;
using System.Xml;
using System.Drawing;
using System.Windows.Forms;

namespace Widgetsphere.Generator.Common.GeneratorFramework
{
	public abstract class ModelObjectTreeNode : TreeNode
	{
		
		public abstract void Refresh();
    protected IModelObjectController _controller = null;

    public IModelObjectController Controller
    {
      get { return _controller; }
    }

    #region Constructor

    public ModelObjectTreeNode(IModelObjectController controller)
    {      
      _controller = controller;
      _controller.ItemChanged += new ItemChanagedEventHandler(ControllerItemChanged);
      _object = _controller.Object;
      this.Refresh();
    }

    private void ControllerItemChanged(object sender, System.EventArgs e)
    {
      this.Object.Dirty = true;
      this.Refresh();
    }

    #endregion

    #region Object

    protected IModelObject _object = null;
    public virtual IModelObject Object
    {
      get { return _object; }
    }

    #endregion

    #region RefreshDeep

    public void RefreshDeep()
		{
      this.RefreshDeep(this);
		}

		private void RefreshDeep(ModelObjectTreeNode node)
		{
      try
      {
        if (node == null)
          return;

        node.Refresh();
				foreach (ModelObjectTreeNode child in node.Nodes)
				{
					this.RefreshDeep(child);
					if (DateTime.Now.Millisecond % 6 == 0)
						System.Windows.Forms.Application.DoEvents();
				}
      }
      catch (Exception ex)
      {
        throw;
      }
    }

    #endregion

    #region Sort

    public void Sort()
    {
      try
      {
        //Sort Nodes
        TreeNode selNode = null;
        if (this.TreeView != null) 
          selNode = this.TreeView.SelectedNode;

        SortedList sortedList = new SortedList();
        foreach (TreeNode node in this.Nodes)
        {
          //Ensure key is unique to avoid error
          string text = node.Text.ToLower();
          string key = text;
          int ii = 0;
          while (sortedList.ContainsKey(key))
          {
            key = text + ii.ToString();
            ii++;
          }
          sortedList.Add(key, node);
        }

        //Cache a sorted node list
        TreeNode[] nodeList = new TreeNode[this.Nodes.Count];
        int index = 0;
        foreach (DictionaryEntry di in sortedList)
        {
          nodeList[index] = (TreeNode)di.Value;
          index++;
        }

        //Loop through the current nodes and determine if the sorted list matches
        bool needUpdate = false;        
        for(int ii=0;ii<nodeList.Length;ii++)
        {
          if (!Util.StringHelper.Match(this.Nodes[ii].Text, nodeList[ii].Text, true))
            needUpdate = true;
        }

        //If the nodes list was in the same order as the 
        //new sortedlist then there is no need to reorder
        if (needUpdate)
        {
          //Clear nodes
          this.Nodes.Clear();

          //Re-add them in order
          if (this.TreeView != null)
            this.TreeView.BeginUpdate();

          foreach (DictionaryEntry di in sortedList)
            this.Nodes.Add((TreeNode)di.Value);

          if (this.TreeView != null)
            this.TreeView.EndUpdate();

          //Reselect previously selected node
          if (this.TreeView != null)
            this.TreeView.SelectedNode = selNode;
        }

      }
      catch (Exception ex)
      {        
        throw;
      }
    }

    #endregion

  }
}
